﻿using DFGK_WMS.IRepository;
using DFGK_WMS.Model.DTO;
using DFGK_WMS.Model.Models;
using DFGK_WMS.Repository;
using DFGK_WMS.WebAPI.Controllers.Result;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Org.BouncyCastle.Crypto;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System.Collections.Generic;
using Microsoft.AspNetCore.Authorization;
using DFGK_WMS.WebAPI.Tools;
using MathNet.Numerics.Distributions;
using Microsoft.Extensions.Caching.Memory;
using System.Security.Claims;
using Advanced.Common;
using NPOI.HSSF.UserModel;
using System.Data;

namespace DFGK_WMS.WebAPI.Controllers.权限管理
{
    /// <summary>
    /// 用户
    /// </summary>
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class UserController : ControllerBase
    {
        private readonly IMemoryCache cache;

        public UserController(IUserRepository userService, ILogRepository logService, TokenHelper tokenHelper,IMemoryCache cache)
        {
            UserService = userService;
            LogService = logService;
            TokenHelper = tokenHelper;
            this.cache = cache;
        }

        public IUserRepository UserService { get; }
        public ILogRepository LogService { get; }
        public TokenHelper TokenHelper { get; }

        /// <summary>
        /// 判断登录
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        [HttpPost]
        [AllowAnonymous]
        public IActionResult GetLogin(LoginDto m)
        {
            if(string.IsNullOrEmpty(m.User_Name) || m.User_Name.Length==0)
            {
                return Ok(BaseResult.Result("400", "账号不能为空！"));
            }
            if (string.IsNullOrEmpty(m.User_Password) || m.User_Password.Length == 0)
            {
                return Ok(BaseResult.Result("400", "密码不能为空！"));
            }
            if (string.IsNullOrEmpty(m.ImgCaptcha) || m.ImgCaptcha.Length == 0)
            {
                return Ok(BaseResult.Result("400", "验证码不能为空！"));
            }
            var captcha = cache.Get("captcha" + HttpContext.Connection.RemoteIpAddress.ToString()).ToString();
            if (captcha is null)
                return Ok(BaseResult.Result("400", "还未请求验证码"));
            if(captcha!=m.ImgCaptcha)
                return Ok(BaseResult.Result("400", "验证码不正确"));
            if (string.IsNullOrEmpty(m.User_Name) || string.IsNullOrEmpty(m.User_Password))
            {
                return Ok(BaseResult.Result("400", "账号密码不能为空"));
            }
            ApiResult apiResult = new ApiResult();
            var obj = UserService.GetLogin(m);
            if (obj != null)
            {
                string? ip = HttpContext.Connection.RemoteIpAddress?.ToString();
                TLog logg = new TLog();
                logg.LogType = 0;
                logg.ActionType = 1;
                logg.ModuleName = "系统登录";
                logg.UserName = obj.UserName;
                logg.RealName = obj.RealName;
                logg.UserId = obj.Id;
                logg.Description = "IP地址为"+ip+"用户名为"+m.User_Name+"，登录成功！";
                //获取前端IP地址
                logg.Ipaddress = ip;

                LogService.AddTLod(logg);
                //返回一个空的密码
                obj.Pwd = string.Empty;
                var token = TokenHelper.CreateJwtToken(obj);
                HttpContext.Response.Headers["token"] = token;
                Response.Headers["Access-Control-Expose-Headers"] = "token";
                obj.Token = token;            
                return Ok(BaseResult.Result(obj, "登录成功！", "200"));
            }
            apiResult.code = "500";
            apiResult.message = "账号密码有误！";
            return Ok(apiResult);
        }

        /// <summary>
        /// 添加用户
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult AddUser(UserRoleDto m)
        {
            ApiResult apiResult = new ApiResult();
            bool IsOK = UserService.AddUser(m);
            if (IsOK)
            {
                apiResult.code = "200";
                apiResult.message = "添加成功！";
                apiResult.data = true;
                return Ok(apiResult);
            }
            apiResult.code = "500";
            apiResult.message = "已经存在该账号！";
            apiResult.data = false;
            return Ok(apiResult);
        }

        /// <summary>
        /// 获取用户
        /// </summary>
        /// <param name="uname">用户名</param>
        /// <param name="rid">角色Id</param>
        /// <param name="state">状态</param>
        /// <param name="pageIndex">当前页数</param>
        /// <param name="pageSize">每页显示条数</param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetUserList(string? uname = "", int rid = 0, int state = 3, int pageIndex = 1, int pageSize = 5)
        {
            if (pageIndex<=0 || pageSize<=0)
            {
                return Ok(BaseResult.Result("400", "分页条件有误！"));
            }
            ApiResult apiResult = new ApiResult();
            int totalCount;
            var list = UserService.GetUserList(uname, rid, state, pageIndex, pageSize, out totalCount);

            if (list != null)
            {
                apiResult.code = "200";
                apiResult.message = "获取成功！";
                apiResult.data = list;
                apiResult.count = totalCount;
                return Ok(apiResult);
            }
            apiResult.code = "500";
            apiResult.message = "获取失败！";
            return Ok(apiResult);
        }

        /// <summary>
        /// 删除用户
        /// </summary>
        /// <param name="uid"></param>
        /// <returns></returns>
        [HttpDelete]
        public IActionResult DelUser(int uid)
        {
            if (uid <= 0)
            {
                return Ok(BaseResult.Result("400", "Id有误！"));
            }
            bool IsOK = UserService.DelUser(uid);
            if (IsOK)
            {
                return Ok(BaseResult.Result(true, "删除成功！", "200"));
            }
            return Ok(BaseResult.Result(false, "删除失败！", "500"));
        }

        /// <summary>
        /// 批量删除
        /// </summary>
        /// <param name="ulist"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult DelUsers(List<TUser> ulist)
        {
            if(ulist.Count==0)
            {
                return Ok(BaseResult.Result( "删除失败！数据不能为空！", "400"));
            }
            bool rule = UserService.DelUsers(ulist);
            if (rule)
            {
                return Ok(BaseResult.Result(true, "删除成功", "200"));
            }
            return Ok(BaseResult.Result(false, "删除失败", "500"));
        }

        /// <summary>
        /// 根据主键获取用户信息
        /// </summary>
        /// <param name="uid"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult URById(int uid)
        {
            if (uid <= 0)
            {
                return Ok(BaseResult.Result("400", "Id有误！"));
            }
            ApiResult apiResult = new ApiResult();
            var obj = UserService.URById(uid);
            if (obj != null)
            {
                return Ok(BaseResult.Result(obj, "获取成功", "200"));
            }
            return Ok(BaseResult.Result(null, "获取失败！", "500"));
        }

        /// <summary>
        /// 修改用户
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        [HttpPut]
        public IActionResult UpdUser(UserRoleDto m)
        {
            if(m.Id<=0)
            {
                return Ok(BaseResult.Result("400", "Id有误！"));
            }
            ApiResult apiResult = new ApiResult();
            bool IsOK = UserService.UpdUser(m);
            if (IsOK)
            {
                apiResult.code = "200";
                apiResult.message = "修改成功！";
                apiResult.data = true;
                return Ok(apiResult);
            }
            apiResult.code = "500";
            apiResult.message = "修改失败！已存在该用户名！";
            apiResult.data = false;
            return Ok(apiResult);
        }

        /// <summary>
        /// 重置密码
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult UserResetPwd(ResetPwdDto m)
        {
            if(m.uid<=0)
            {
                return Ok(BaseResult.Result("400", "Id有误！"));
            }
            ApiResult apiResult = new ApiResult();
            bool IsOK = UserService.UserResetPwd(m);
            if (IsOK)
            {
                apiResult.code = "200";
                apiResult.data = IsOK;
                apiResult.message = "重置密码成功！";
                return Ok(apiResult);
            }

            apiResult.code = "500";
            apiResult.data = IsOK;
            apiResult.message = "重置密码失败！";
            return Ok(apiResult);
        }

        /// <summary>
        /// 修改密码
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        [HttpPut]
        public IActionResult UserModifyPwd(ModifyPwdDto m)
        {
            if(string.IsNullOrEmpty(m.NewPwd))
            {
                return Ok(BaseResult.Result("400", "新密码不能为空！"));
            }
            ApiResult apiResult = new ApiResult();
            bool IsOK = UserService.UserModifyPwd(m);
            if (IsOK)
            {
                apiResult.code = "200";
                apiResult.message = "修改成功！";
                apiResult.data = true;
                return Ok(apiResult);
            }
            apiResult.code = "500";
            apiResult.message = "修改失败，当前密码不一致！请重新输入！";
            apiResult.data = false;
            return Ok(apiResult);
        }
        MemoryStream ProcessExcelData()
        {
            //模块从表中读取的数据
            List<TUser> list = new List<TUser>();
            list = UserService.GetUserExcel();
            // 已经读取出了正确的数据后
            //创建Excel对象把数据赋值到对象中
            IWorkbook workbook = new XSSFWorkbook(); // Excel对象
            ISheet sheet1 = workbook.CreateSheet("用户管理");  // 创建Excel中的表对象
            //表头
            IRow row0 = sheet1.CreateRow(0);  // 在sheet1表格中创建第0行
            row0.CreateCell(0).SetCellValue("序号"); // 在sheet1表格中第0行创建第0列，并且在给这个单元格赋值
            row0.CreateCell(1).SetCellValue("用户名称");
            row0.CreateCell(2).SetCellValue("工号");
            row0.CreateCell(3).SetCellValue("真实姓名");
            row0.CreateCell(4).SetCellValue("手机号");
            row0.CreateCell(5).SetCellValue("状态");
            row0.CreateCell(6).SetCellValue("创建时间");
            var rowIndex = 1;
            foreach (var item in list)
            {
                var st = "";
                if (item.Status == 1)
                {
                    st = "启用";
                }
                if (item.Status == 0)
                {
                    st = "禁用";
                }
                IRow row = sheet1.CreateRow(rowIndex);
                row.CreateCell(0).SetCellValue(item.Id);
                row.CreateCell(1).SetCellValue(item.UserName);
                row.CreateCell(2).SetCellValue(item.JobNo);
                row.CreateCell(3).SetCellValue(item.RealName);
                row.CreateCell(4).SetCellValue(item.MobilePhone);
                row.CreateCell(5).SetCellValue(st);
                row.CreateCell(6).SetCellValue(item.CreateDate.ToString());
                rowIndex++;
            }
            MemoryStream ms = new MemoryStream();
            workbook.Write(ms);

            return ms;
        }
        /// <summary>
        /// 导出用户信息
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public FileContentResult DownUser()
        {
            MemoryStream ms = ProcessExcelData();
            byte[] fileBytes = ms.ToArray();
            return File(fileBytes, System.Net.Mime.MediaTypeNames.Application.Octet, "用户信息.xlsx"); //关键语句
        }

        /// <summary>
        /// 修改用户状态
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        [HttpPut]
        public IActionResult UpdUserStatus(UpdStatusDto m)
        {   
            if(m.Id<=0)
            {
                return Ok(BaseResult.Result( "400", "用户Id有误"));
            }
            bool rule = UserService.UpdUserStatus(m);
            if (rule)
            {
                return Ok(BaseResult.Result(true, "修改成功", "200"));
            }
            return Ok(BaseResult.Result(false, "修改失败", "500"));
        }
        /// <summary>
        /// 生成图形验证码
        /// </summary>
        /// <returns></returns>
        [HttpGet, AllowAnonymous]
        public IActionResult GetCaptcha()
        {
            var codeVal = Utils.GenerateRandomCaptcha().ToLower();
            cache.Set("captcha" + HttpContext.Connection.RemoteIpAddress.ToString(), codeVal);
            var imageData = Utils.GetCaptchaImage(codeVal);
            var base64img = new FileContentResult(imageData, "image/png").FileContents;
            return Ok(BaseResult.Result(new { codeVal, base64img },"200"));
        }

        /// <summary>
        /// 导入（暂时弃用）
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public IActionResult ImportExcelOnFormSubmit()
        {
            //获取上传的Excel文件
            IFormFile file = Request.Form.Files["file"];
            if (file != null && file.Length > 0)
            {
                string suffixName = Path.GetExtension(file.FileName).ToLower();
                if (suffixName != ".xls" && suffixName != ".xlsx")
                {
                    return Content("请导入文件为Excel格式");
                }
                HSSFWorkbook hSSFWorkbook = new HSSFWorkbook(file.OpenReadStream());
                List<DataTable> datatableList = ExcelOperationHelper.ToExcelDateTable(hSSFWorkbook);             
                List<TUser> users= ExcelOperationHelper.DataTableToList<TUser>(datatableList);
                bool result = UserService.AddUserList(users);
                if(result)
                {
                    return Ok(BaseResult.Result(true, "导入成功！", "200"));
                }
             
            }
            return Ok(BaseResult.Result(false, "导入失败！", "500"));

        }

        /// <summary>
        /// 导入Excel文件
        /// </summary>
        /// <param name="excelFile"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult UploadUserInfo(IFormFile excelFile)
        {
            try
            {
                var postFile = Request.Form.Files[0];
                string extName = Path.GetExtension(postFile.FileName);
                if (!new string[] { ".xls", ".xlsx" }.Contains(extName))
                {
                    return Ok(new
                    {
                        error = 1,
                        msg = "必须是Excel文件"
                    });
                }

                MemoryStream ms = new MemoryStream();
                postFile.CopyTo(ms);
                ms.Position = 0;
                IWorkbook wb = null;
                if (extName.ToLower().Equals(".xls")) // 97-2003版本
                {
                    wb = new HSSFWorkbook(ms);
                }
                else
                {
                    wb = new XSSFWorkbook(ms); // 2007以上版本
                }

                ISheet sheet = wb.GetSheetAt(0);

                //总行数（0开始）
                int totalRow = sheet.LastRowNum;
                // 总列数（1开始）
                int totalColumn = sheet.GetRow(0).LastCellNum;

                List<TUser> stuList = new();
                for (int i = 1; i <= totalRow; i++)
                {

                    IRow row = sheet.GetRow(i);
                  
                    string UserName = row.GetCell(0).StringCellValue;
                    string RealName = row.GetCell(1).StringCellValue;
                    string Pwd = "";
                    if(row.GetCell(2).CellType==CellType.String)
                    {
                         Pwd = row.GetCell(2).StringCellValue;
                    }
                    else
                    {
                         Pwd = row.GetCell(2).NumericCellValue.ToString();
                    }                
                    string? HeadShot = row.GetCell(3)?.StringCellValue;
                    int Status = row.GetCell(4).StringCellValue=="启用"?1:0;
                    int Gender = row.GetCell(5).StringCellValue=="男"?0:1;
                    string MobilePhone = ((long)row.GetCell(6).NumericCellValue).ToString();
                    string Email = row.GetCell(7).StringCellValue;
                    string Remark = row.GetCell(8).StringCellValue;
                    int CreateUserId = (int)row.GetCell(9).NumericCellValue;
                    //string Phone = ((long)row.GetCell(2).NumericCellValue).ToString();
                    string CreateUserName = row.GetCell(10).StringCellValue;
                    DateTime CreateDate = row.GetCell(11).DateCellValue;
                    int ModifyUserId = (int)row.GetCell(12).NumericCellValue;
                    string ModifyUserName = row.GetCell(13).StringCellValue;
                    DateTime ModifyDate = row.GetCell(14).DateCellValue;
                    

                    var user = new TUser
                    {
                        UserName = UserName,
                        RealName= RealName,
                        Pwd= Pwd,
                        HeadShot= HeadShot,
                        Status= Status,
                        Gender = Gender,
                        MobilePhone = MobilePhone,
                        Email= Email,
                        Remark= Remark,
                        CreateUserId= CreateUserId,
                        CreateUserName= CreateUserName,
                        CreateDate= CreateDate,
                        ModifyUserId= ModifyUserId,
                        ModifyUserName= ModifyUserName,
                        ModifyDate= ModifyDate,
                    };
                    stuList.Add(user);
                }
                UserService.AddUserList(stuList);
                wb.Close();
                return Ok(new
                {
                    error = 0,
                    importCount = stuList.Count,
                    msg = ""
                });
            }
            catch (Exception)
            {
                throw;
            }
        }
    }
}
